package cn.edu.cug.cs.gtl.docsrv.doc;

import cn.edu.cug.cs.gtl.mybatis.Session;
import cn.edu.cug.cs.gtl.mybatis.mapper.doc.*;
import cn.edu.cug.cs.gtl.mybatis.metadata.DocUtils;
import cn.edu.cug.cs.gtl.net.ftp.client.ClientFTP;
import cn.edu.cug.cs.gtl.protos.TimeValue;
import cn.edu.cug.cs.gtl.protoswrapper.TimeValueWrapper;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 基于关系数据库Oracle实现的文档数据管理器
 * DOC_ITEM表中存放文档数据的条目信息
 * DOC_FILE数据表中存放文档文件
 * 这两个表通过DOC_INTERNAL_ID关联
 */
public class RDBDocManager extends DocManager{
    /**
     * 构造函数
     *
     * @param s
     */
    public RDBDocManager(Session s) {
        super(s);
    }

    @Override
    public boolean insert(DocAll docAll) {
        return super.insert(DocUtils.fromDocAll(docAll).getFirst(),DocUtils.fromDocAll(docAll).getSecond());
    }

    @Override
    public boolean delete(DocAll docAll) {
        return super.delete(DocUtils.fromDocAll(docAll).getFirst());
    }

    @Override
    public boolean update(DocAll docAll) {
        return super.update(DocUtils.fromDocAll(docAll).getFirst(),DocUtils.fromDocAll(docAll).getSecond());
    }


    @Override
    public DocAll queryByInternalId(BigDecimal docInternalId) {
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);

        DocItem docItem =  docItemMapper.selectByPrimaryKey(docInternalId);
        DocFile docFile = docFileMapper.selectByPrimaryKey(docInternalId);
        DocAll docAll = DocUtils.toDocAll(docItem,docFile);
        session.commit();
        return docAll;
    }

    @Override
    public List<DocAll> queryByTitle(String docEnTitle) {
        List<DocAll> res = new ArrayList<>();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
        List<DocItem> docItems =  docItemMapper.selectByEnTitle(docEnTitle);
        for(DocItem docItem : docItems){
            DocFile docFile = docFileMapper.selectByPrimaryKey(docItem.getDocInternalId());
            DocAll docAll = DocUtils.toDocAll(docItem,docFile);
            res.add(docAll);
        }
        session.commit();
        return res;
    }

    @Override
    public List<DocAll> queryByComment(String docCnTitle) {
        List<DocAll> res = new ArrayList<>();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
        List<DocItem> docItems =  docItemMapper.selectByCnTitle(docCnTitle);
        for(DocItem docItem : docItems){
            DocFile docFile = docFileMapper.selectByPrimaryKey(docItem.getDocInternalId());
            DocAll docAll = DocUtils.toDocAll(docItem,docFile);
            res.add(docAll);
        }
        session.commit();
        return res;

    }

    @Override
    public List<DocAll> queryByType(String docType) {
        List<DocAll> res = new ArrayList<>();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
        List<DocItem> docItems =  docItemMapper.selectByType(docType);
        for(DocItem docItem : docItems){
            DocFile docFile = docFileMapper.selectByPrimaryKey(docItem.getDocInternalId());
            DocAll docAll = DocUtils.toDocAll(docItem,docFile);
            res.add(docAll);
        }
        session.commit();
        return res;
    }

    @Override
    public List<DocAll> queryByAppendDate(TimeValue begin, TimeValue end) {
        List<DocAll> res = new ArrayList<>();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
        List<DocItem> docItems =  docItemMapper.selectByAppendDate(TimeValueWrapper.toUtilDate(begin),TimeValueWrapper.toUtilDate(end));
        for(DocItem docItem : docItems){
            DocFile docFile = docFileMapper.selectByPrimaryKey(docItem.getDocInternalId());
            DocAll docAll = DocUtils.toDocAll(docItem,docFile);
            res.add(docAll);
        }
        session.commit();
        return res;
    }





    @Override
    public boolean insert(DocItem docItem, String localSingleFile) {
        File file = new File(localSingleFile);
        if(file.exists()){
            DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
            DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
            if( docItem.getDocInternalId() == null){
                docItem.setDocInternalId(docItemMapper.nextDocInternalId());
            }
            DocFile docFile = new DocFile();
            docFile.setDocInternalId(docItem.getDocInternalId());
            FileInputStream fileInputStream;
            ByteArrayOutputStream out;
            try{
                fileInputStream = new FileInputStream(file);
                out = new ByteArrayOutputStream(1000);
                byte[] b = new byte[1000];
                int n;
                while ((n = fileInputStream.read(b)) != -1) {
                    out.write(b, 0, n);
                }
                docFile.setDocRawBytes(out.toByteArray());
                docFileMapper.insert(docFile);
                docItemMapper.insert(docItem);

                fileInputStream.close();
                out.close();

            }catch (IOException e){
                e.printStackTrace();
            }
            session.commit();
            return true;
        }
        return false;
    }

    @Override
    public boolean insert(String localDir) {
        File file = new File(localDir);
        if(file.isDirectory()){
            File[] files = file.listFiles();
            for (File f : files){
                DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
                DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
                DocItem docItem = new DocItem();
                DocFile docFile = new DocFile();
                docItem.setDocInternalId(docItemMapper.nextDocInternalId());
                docFile.setDocInternalId(docItem.getDocInternalId());

                FileInputStream fileInputStream;
                ByteArrayOutputStream out;
                try{
                    fileInputStream = new FileInputStream(file);
                    out = new ByteArrayOutputStream(1000);
                    byte[] b = new byte[1000];
                    int n;
                    while ((n = fileInputStream.read(b)) != -1) {
                        out.write(b, 0, n);
                    }
                    docFile.setDocRawBytes(out.toByteArray());
                    docFileMapper.insert(docFile);

                    docItem.setDocAppendDate(new Date());
                    docItem.setDocEnTitle(f.getName());
                    docItemMapper.insert(docItem);
                    fileInputStream.close();
                    out.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
            session.commit();
            return true;
        }
        return false;
    }


}
